<?php


/**
 * RaiseDbTransact class
 * provides functionality for transactions
 *
 * @author Sam-Mauris Yong <hellclanner at live dot com>
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package Raise.Core.DataAccess
 * @since 1.2
 */

class RaiseDbTransact extends RaiseObject {

    /**
     * The RaiseDbConnection assosciated with this RaiseDbTransact object
     * @var RaiseDbConnection
     */
    private $connection;

    /**
     * Flags whether the current connection is in transaction or not
     * @var boolean
     */
    private static $inTransaction = false;

    /**
     * Create a new RaiseDbTransact object
     * @param RaiseDbConnection $connection 
     */
    function __construct($connection) {
        $this->connection = $connection;
    }


    /**
     * Get the connection of this command
     * @return RaiseDbConnection
     */
    public function connection(){
        return $this->connection;
    }

    /**
     * Get whether the current transaction is open or not.
     * @return boolean
     */
    public static function inTransaction(){
        return self::$inTransaction;
    }

    /**
     * Begin the transaction
     * @return boolean
     */
    public function begin(){
        if(self::$inTransaction){
            throw new RaiseInvalidRequestException('Cannot begin a new transaction when another transaction is on-going');
        }
        $cmd = new RaiseDbCommand($this->connection, $this->connection->adapter()->transactBegin());
        $ok =  $cmd->executeNonQuery();
        if($ok){
            self::$inTransaction = true;
        }
        return $ok;
    }

    /**
     * Commit the changes to the database made in the transaction
     * @return boolean
     */
    public function commit(){
        if(!self::$inTransaction){
            throw new RaiseInvalidRequestException('Cannot commit when no transaction is on-going');
        }
        $cmd = new RaiseDbCommand($this->connection, $this->connection->adapter()->transactCommit());
        $ok = $cmd->executeNonQuery();
        if($ok){
            self::$inTransaction = false;
        }
        return $ok;
    }

    /**
     * Revert the changes to the database made in the transaction
     * @return boolean
     */
    public function rollback(){
        if(!self::$inTransaction){
            throw new RaiseInvalidRequestException('Cannot rollback when no transaction is on-going');
        }
        $cmd = new RaiseDbCommand($this->connection, $this->connection->adapter()->transactRollback());
        $ok =  $cmd->executeNonQuery();
        if($ok){
            self::$inTransaction = false;
        }
        return $ok;
    }

}
